<template>
  <div>
    <el-form ref="deptForm" :rules="rules" :model="form" label-width="120px">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="form.name" style="width:80%" placeholder="2-10个字符" />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="form.code" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select v-model="form.manager" style="width:80%" placeholder="请选择">
          <!-- value 值是为了提交给后台的, 所以需要看后台要什么, 咱们传什么 -->
          <el-option v-for="item in employees" :key="item.id" :value="item.username" :label="item.username" />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="form.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" :rows="3" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="small" @click="hSubmit">确定</el-button>
        <el-button size="small" @click="hCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import { getEmployeeSimple } from '@/api/employees'
import { addDepartment, getDepartDetail, updateDepartments } from '@/api/departments.js'
export default {
  name: 'AddOrEdit', // 方便vue查看
  props: { // 接收父组件传过来的id 用于发请求
    id: {
      type: String,
      required: true
    },
    isEdit: {
      type: Boolean,
      required: true
    },
    originList: {
      type: Array,
      required: true
    }
  },

  data() {
    const validCode = (rule, value, cb) => { // 部门编号 校验
      // 点击编辑时, 部门编码 blur 会有Bug
      // const result = this.originList.some(item => item.code === value)
      // if (result) cb(new Error(value + '已经存在'))
      // else cb()

      // 正确做法:
      /* 1. 不可以拿 value 去做判断, 而是要找到 当前正在编辑哪个部门 (this.id)
         2. 根据 id 去 原数组中筛选出 不包含此部门 之外的所有部门 (得到一个数组)
         3. 再将数组 map 映射成 codeList  */
      let codeList = []
      if (this.isEdit) { // 编辑状态下: 当前部门编号可以使用 ; 已有的部门编号 不可使用  (做法:之前父传子的 id帮忙 筛选出不包含此部门的数组 )
        codeList = this.originList.filter(item => this.id !== item.id).map(item => item.code)
      } else { // 添加状态下: 已有的部门编号 不可使用
        codeList = this.originList.map(item => item.code)
      }

      // 判断 用户输入的部门编号 在不在codeList中 , '在'就不通过 , '不在'就通过
      if (codeList.includes(value)) cb(new Error(value + '已经存在'))
      else cb()
    }
    const validName = (rule, value, cb) => { // 部门名称 校验
      // 需求: 根据 id 找到 当前点击部门的 所有子部门
      // 当前部门的 id: this.id
      // 找到所有子部门 pid, 并映射出所有的 name 属性
      let nameList = []
      if (this.isEdit) { // 编辑状态下:
        const pid = this.originList.find(item => item.id === this.id).pid
        nameList = this.originList.filter(item => item.pid === pid && item.id !== this.id).map(item => item.name)
        console.log(value + '-的兄弟部门:' + nameList)
      } else { // 添加状态下:
        nameList = this.originList.filter(item => item.pid === this.id).map(item => item.name)
        console.log('当前部门的子部门:' + nameList)
      }
      // console.log(nameList)
      if (nameList.includes(value)) cb(new Error(value + '已经存在'))
      else cb()
    }
    return {
      form: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      employees: [], // 员工列表
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' },
          { min: 2, max: 10, message: '部门名称要求2-10个字符', trigger: 'blur' },
          { validator: validName, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: 'blur' },
          { validator: validCode, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: 'change' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: 'blur' },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: 'blur' }
        ]
      }
    }
  },
  // watch: { // 方案3: 监听id变化后, 调用 部门详情 请求
  //   id: {
  //     handler(newVal, oldVal) {
  //       this.loadDepartDetail() // 监听到id变化后, 调用 部门详情 请求
  //     },
  //     deep: true, // 深度侦听, 此处不需要
  //     immediate: true // 第一次数据赋值 是不会触发侦听的, 设置 immediate 后 第一次也会侦听
  //   }
  // },
  created() {
    // 不论添加还是编辑 都要发送
    this.loadEmployees()
    // 只有编辑部门时 才发送
    this.loadDepartDetail()
  },
  methods: {
    hSubmit() { // 用户点击了 确定
      // 代码优化: 添加 和 编辑 只有调用的接口不同, 所以封装到一个函数内
      // 1. 兜底校验
      this.$refs.deptForm.validate(async valid => { // validate 是异步的
        if (!valid) return
        try { // try-catch 必须紧贴着要捕获异常的代码块, 中间不能间隔异步代码 ,validate就是异步代码
          // 2. 发请求拿结果
          let res = null
          if (this.isEdit) {
            res = await updateDepartments(this.form)
          } else {
            res = await addDepartment({ ...this.form, pid: this.id })
          }
          // 3. 根据结果提醒用户
          this.$message.success(res.message)
          // 4. 关闭 dialog
          // 5. 通知父组件更新数据
          this.$emit('success')
        } catch (e) {
          this.$message.error(e.message)
        }
      })
      // this.isEdit ? this.doEdit() : this.doAdd()
    },
    // async doEdit() {
    //   try {
    //     // 1. 兜底校验 (暂时不做)
    //     // 2. 发请求拿结果
    //     const res = await updateDepartments(this.form)
    //     // console.log(res)
    //     // 3. 根据结果提醒用户
    //     this.$message.success(res.message)
    //     // 4. 关闭 dialog
    //     // 5. 通知父组件更新数据
    //     this.$emit('success')
    //   } catch (e) {
    //     this.$message.error(e.message)
    //   }
    // },
    // async doAdd() {
    //   try {
    //     // 1. 兜底校验 (暂时不做)
    //     // 2. 发请求拿结果
    //     // this.form.pid = this.id
    //     const res = await addDepartment({ ...this.form, pid: this.id })

    //     console.log(res)
    //     // 3. 根据结果提醒用户
    //     this.$message.success(res.message)

    //     // 4. 关闭 dialog
    //     // 5. 通知父组件更新数据
    //     this.$emit('success')
    //   } catch (e) {
    //     this.$message.error(e.message)
    //   }
    // },
    hCancel() { // 点击了取消, 通知父组件 关闭对话框
      this.$emit('close')
    },
    async loadEmployees() { // 获取员工列表 渲染下拉菜单
      const res = await getEmployeeSimple()
      // console.log(res)
      this.employees = res.data
    },
    async loadDepartDetail() { // 对话框组件加载时 判断是否为编辑, 决定是否发 获取部门详情的请求
      if (!this.isEdit) return
      try {
        const res = await getDepartDetail(this.id)
        // 数据回填
        this.form = res.data
      } catch (e) {
        console.dir('获取部门详情失败,原因:', e)
      }
    }
  }

}
</script>
